#include "Resolver.h"

#include <cstring>

#include <sys/socket.h>
#include <netdb.h>

// ================================================================================

std::string CachingResolver::resolveNoCache(IPAddress ipAddr) {
  struct sockaddr_in sa;
  char hostName[256];

  sa.sin_family = AF_INET;
  sa.sin_port = 0;
  sa.sin_addr.s_addr = ipAddr;
  memset(hostName, 0, sizeof(hostName));
  getnameinfo((const struct sockaddr*)&sa, sizeof(sa), hostName, sizeof(hostName), NULL, 0, 0);

  return std::string(hostName);
}

std::string CachingResolver::resolve(IPAddress ipAddr) {
  time_t now = time(NULL);
  Cache::iterator entry = cache.find(ipAddr);

  if (entry != cache.end()) {
    if (now - entry->second.cacheTime < 60*60) {  // We hold the resolved name cache for 1 hour
      return entry->second.name;
    } else {
      entry->second.name = resolveNoCache(ipAddr);
      return entry->second.name;
    }
  } else {
    std::string res = resolveNoCache(ipAddr);
    cache.insert(std::make_pair(ipAddr, CacheEntry(res)));

    return res;
  }
}
